package com.doufeng.dispatch.controller;

import com.doufeng.common.result.Result;
import com.doufeng.dispatch.dto.TaskCreateDTO;
import com.doufeng.dispatch.dto.TaskNearByVO;
import com.doufeng.dispatch.entity.Task;
import com.doufeng.dispatch.service.TaskService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.domain.geo.Metrics;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dispatch/inner")
public class DispatchInnerController {

    @Resource
    private TaskService taskService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 订单支付成功后调用：创建可抢任务 + Geo 索引
     */
    @PostMapping("/task")
    public Result<Long> createTask(@RequestBody TaskCreateDTO dto) {
        return Result.success(
                taskService.createTask(dto.getOrderId(), dto.getLng(), dto.getLat())
        );
    }

    /**
     * 附近任务（Geo 半径 + 按支付时间升序 = 先到先得）
     */
    @GetMapping("/nearby")
    public Result<List<TaskNearByVO>> nearby(
            @RequestParam(value = "lng") Double lng,
            @RequestParam(value = "lat") Double lat,
            @RequestParam(value = "radiusKm", defaultValue = "5") Double radiusKm,
            @RequestParam(value = "limit", defaultValue = "20") Integer limit) {

        // 1. Geo 半径搜索（Redis）
        Circle circle = new Circle(new Point(lng, lat), new Distance(radiusKm, Metrics.KILOMETERS));
        GeoResults<RedisGeoCommands.GeoLocation<String>> results =
                stringRedisTemplate.opsForGeo().radius("task:geo", circle);

        if (results == null || results.getContent().isEmpty()) {
            return Result.success(List.of());
        }

        // 2. 回表 + 按支付时间升序
        List<Long> taskIds = results.getContent().stream()
                .map(geo -> Long.valueOf(geo.getContent().getName()))
                .limit(limit)
                .collect(Collectors.toList());

        List<TaskNearByVO> list = taskService.lambdaQuery()
                .in(Task::getId, taskIds)
                .orderByAsc(Task::getPayTime)   // ← 先到先得肉眼可见
                .list()
                .stream()
                .map(t -> new TaskNearByVO(t.getId(), t.getOrderId(), t.getPayTime()))
                .collect(Collectors.toList());

        return Result.success(list);
    }
}